%{
#include "bison_parser.h"
#include <stdio.h>
#include <sstream>
#include <string>
#include <cstring>
#define TOKEN(name) { return SQL_##name; }
static thread_local std::stringstream strbuf;
%}

%{

#define YYLTYPE_IS_DECLARED 1

#define YY_USER_ACTION \
    yylloc->first_line = yylloc->last_line; \
    yylloc->first_column = yylloc->last_column; \
    for(int i = 0; yytext[i] != '\0'; i++) { \
        if(yytext[i] == '\n') { \
            yylloc->last_line++; \
            yylloc->last_column = 0; \
        } \
        else { \
            yylloc->last_column++; \
        } \
    }   
%}

%option reentrant
%option bison-bridge
%option never-interactive
%option batch
%option noyywrap
%option nounput
%option warn
%option case-insensitive
%option bison-locations
%option header-file="flex_lexer.h"
%option outfile="flex_lexer.cpp"
%option prefix="ff_"
%s COMMENT
%x singlequotedstring

%%

";"		TOKEN(OP_SEMI)
FROM		TOKEN(FROM)
DELETE		TOKEN(DELETE)
QUICK		TOKEN(QUICK)
LOW_PRIORITY		TOKEN(LOW_PRIORITY)
IGNORE		TOKEN(IGNORE)
ALTER		TOKEN(ALTER)
TABLE		TOKEN(TABLE)
","		TOKEN(OP_COMMA)
ADD		TOKEN(ADD)
COLUMN		TOKEN(COLUMN)
")"		TOKEN(OP_RP)
"("		TOKEN(OP_LP)
CHANGE		TOKEN(CHANGE)
MODIFY		TOKEN(MODIFY)
DROP		TOKEN(DROP)
FOREIGN		TOKEN(FOREIGN)
KEY		TOKEN(KEY)
PRIMARY		TOKEN(PRIMARY)
INDEX		TOKEN(INDEX)
CHECK		TOKEN(CHECK)
CONSTRAINT		TOKEN(CONSTRAINT)
SET		TOKEN(SET)
DEFAULT		TOKEN(DEFAULT)
RENAME		TOKEN(RENAME)
TO		TOKEN(TO)
AFTER		TOKEN(AFTER)
FIRST		TOKEN(FIRST)
ON		TOKEN(ON)
IF		TOKEN(IF)
EXISTS		TOKEN(EXISTS)
VIEW		TOKEN(VIEW)
UPDATE		TOKEN(UPDATE)
LIMIT		TOKEN(LIMIT)
INTO		TOKEN(INTO)
INSERT		TOKEN(INSERT)
VALUES		TOKEN(VALUES)
AS		TOKEN(AS)
DUPLICATE		TOKEN(DUPLICATE)
"="		TOKEN(OP_EQUAL)
DELAYED		TOKEN(DELAYED)
HIGH_PRIORITY		TOKEN(HIGH_PRIORITY)
CREATE		TOKEN(CREATE)
UNIQUE		TOKEN(UNIQUE)
OR		TOKEN(OR)
REPLACE		TOKEN(REPLACE)
ALGORITHM		TOKEN(ALGORITHM)
UNDEFINED		TOKEN(UNDEFINED)
MERGE		TOKEN(MERGE)
TEMPTABLE		TOKEN(TEMPTABLE)
TEMPORARY		TOKEN(TEMPORARY)
NOT		TOKEN(NOT)
CHAR		TOKEN(CHAR)
BINARY		TOKEN(BINARY)
VARCHAR		TOKEN(VARCHAR)
VARBINARY		TOKEN(VARBINARY)
LONG		TOKEN(LONG)
TINYBLOB		TOKEN(TINYBLOB)
MEDIUMBLOB		TOKEN(MEDIUMBLOB)
LONGBLOB		TOKEN(LONGBLOB)
BLOB		TOKEN(BLOB)
TINYTEXT		TOKEN(TINYTEXT)
MEDIUMTEXT		TOKEN(MEDIUMTEXT)
LONGTEXT		TOKEN(LONGTEXT)
TEXT		TOKEN(TEXT)
BOOL		TOKEN(BOOL)
BOOLEAN		TOKEN(BOOLEAN)
FLOAT		TOKEN(FLOAT)
DECIMAL		TOKEN(DECIMAL)
NUMERIC		TOKEN(NUMERIC)
FIXED		TOKEN(FIXED)
REAL		TOKEN(REAL)
DOUBLE		TOKEN(DOUBLE)
INT		TOKEN(INT)
TINYINT		TOKEN(TINYINT)
SMALLINT		TOKEN(SMALLINT)
MEDIUMINT		TOKEN(MEDIUMINT)
BIGINT		TOKEN(BIGINT)
SIGNED		TOKEN(SIGNED)
UNSIGNED		TOKEN(UNSIGNED)
ZEROFILL		TOKEN(ZEROFILL)
NULL		TOKEN(NULL)
VISIBLE		TOKEN(VISIBLE)
INVISIBLE		TOKEN(INVISIBLE)
REFERENCES		TOKEN(REFERENCES)
CASCADE		TOKEN(CASCADE)
NO		TOKEN(NO)
ACTION		TOKEN(ACTION)
UNION		TOKEN(UNION)
EXCEPT		TOKEN(EXCEPT)
INTERSECT		TOKEN(INTERSECT)
SELECT		TOKEN(SELECT)
WINDOW		TOKEN(WINDOW)
PARTITION		TOKEN(PARTITION)
BY		TOKEN(BY)
ORDER		TOKEN(ORDER)
ASC		TOKEN(ASC)
DESC		TOKEN(DESC)
ROWS		TOKEN(ROWS)
RANGE		TOKEN(RANGE)
UNBOUNDED		TOKEN(UNBOUNDED)
PRECEDING		TOKEN(PRECEDING)
CURRENT		TOKEN(CURRENT)
ROW		TOKEN(ROW)
AND		TOKEN(AND)
BETWEEN		TOKEN(BETWEEN)
FOLLOWING		TOKEN(FOLLOWING)
HAVING		TOKEN(HAVING)
GROUP		TOKEN(GROUP)
WITH		TOKEN(WITH)
ROLLUP		TOKEN(ROLLUP)
WHERE		TOKEN(WHERE)
LATERAL		TOKEN(LATERAL)
USING		TOKEN(USING)
JOIN		TOKEN(JOIN)
INNER		TOKEN(INNER)
CROSS		TOKEN(CROSS)
STRAIGHT_JOIN		TOKEN(STRAIGHT_JOIN)
NATURAL		TOKEN(NATURAL)
RIGHT		TOKEN(RIGHT)
LEFT		TOKEN(LEFT)
OUTER		TOKEN(OUTER)
"*"		TOKEN(OP_MUL)
"."		TOKEN(OP_DOT)
SQL_NO_CACHE		TOKEN(SQL_NO_CACHE)
DISTINCT		TOKEN(DISTINCT)
SQL_SMALL_RESULT		TOKEN(SQL_SMALL_RESULT)
SQL_BIG_RESULT		TOKEN(SQL_BIG_RESULT)
SQL_BUFFER_RESULT		TOKEN(SQL_BUFFER_RESULT)
SQL_CALC_FOUND_ROWS		TOKEN(SQL_CALC_FOUND_ROWS)
ALL		TOKEN(ALL)
RECURSIVE		TOKEN(RECURSIVE)
XOR		TOKEN(XOR)
IS		TOKEN(IS)
TRUE		TOKEN(TRUE)
FALSE		TOKEN(FALSE)
UNKNOWN		TOKEN(UNKNOWN)
IN		TOKEN(IN)
SOUNDS		TOKEN(SOUNDS)
LIKE		TOKEN(LIKE)
REGEXP		TOKEN(REGEXP)
"|"		TOKEN(OP_OR)
"&"		TOKEN(OP_AND)
"<<"		TOKEN(OP_SHL)
">>"		TOKEN(OP_SHR)
"+"		TOKEN(OP_ADD)
"-"		TOKEN(OP_SUB)
"/"		TOKEN(OP_DIVIDE)
"%"		TOKEN(OP_MOD)
"^"		TOKEN(OP_XOR)
"~"		TOKEN(OP_NOT)
ASCII		TOKEN(ASCII)
BIN		TOKEN(BIN)
BIT_LENGTH		TOKEN(BIT_LENGTH)
CHAR_LENGTH		TOKEN(CHAR_LENGTH)
LENGTH		TOKEN(LENGTH)
LOWER		TOKEN(LOWER)
LTRIM		TOKEN(LTRIM)
OCT		TOKEN(OCT)
ORD		TOKEN(ORD)
QUOTE		TOKEN(QUOTE)
REVERSE		TOKEN(REVERSE)
RTRIM		TOKEN(RTRIM)
SPACE		TOKEN(SPACE)
TRIM		TOKEN(TRIM)
LEADING		TOKEN(LEADING)
TRAILING		TOKEN(TRAILING)
UNHEX		TOKEN(UNHEX)
UPPER		TOKEN(UPPER)
FIND_IN_SET		TOKEN(FIND_IN_SET)
INSTR		TOKEN(INSTR)
LOCATE		TOKEN(LOCATE)
REPEAT		TOKEN(REPEAT)
SUBSTRING		TOKEN(SUBSTRING)
EXPORT_SET		TOKEN(EXPORT_SET)
LPAD		TOKEN(LPAD)
RPAD		TOKEN(RPAD)
SUBSTRING_INDEX		TOKEN(SUBSTRING_INDEX)
CONCAT		TOKEN(CONCAT)
CONCAT_WS		TOKEN(CONCAT_WS)
ELT		TOKEN(ELT)
FIELD		TOKEN(FIELD)
MAKE_SET		TOKEN(MAKE_SET)
PI		TOKEN(PI)
RAND		TOKEN(RAND)
ABS		TOKEN(ABS)
ACOS		TOKEN(ACOS)
ASIN		TOKEN(ASIN)
ATAN		TOKEN(ATAN)
CEILING		TOKEN(CEILING)
COS		TOKEN(COS)
COT		TOKEN(COT)
DEGREES		TOKEN(DEGREES)
EXP		TOKEN(EXP)
FLOOR		TOKEN(FLOOR)
HEX		TOKEN(HEX)
LN		TOKEN(LN)
RADIANS		TOKEN(RADIANS)
ROUND		TOKEN(ROUND)
SIGN		TOKEN(SIGN)
SIN		TOKEN(SIN)
SQRT		TOKEN(SQRT)
TAN		TOKEN(TAN)
FORMAT		TOKEN(FORMAT)
LOG		TOKEN(LOG)
MOD		TOKEN(MOD)
POW		TOKEN(POW)
TRUNCATE		TOKEN(TRUNCATE)
CONV		TOKEN(CONV)
ROW_NUMBER		TOKEN(ROW_NUMBER)
RANK		TOKEN(RANK)
DENSE_RANK		TOKEN(DENSE_RANK)
CUME_DIST		TOKEN(CUME_DIST)
PERCENT_RANK		TOKEN(PERCENT_RANK)
NTILE		TOKEN(NTILE)
LEAD		TOKEN(LEAD)
LAG		TOKEN(LAG)
FIRST_VALUE		TOKEN(FIRST_VALUE)
LAST_VALUE		TOKEN(LAST_VALUE)
NTH_VALUE		TOKEN(NTH_VALUE)
RESPECT		TOKEN(RESPECT)
NULLS		TOKEN(NULLS)
LAST		TOKEN(LAST)
AVG		TOKEN(AVG)
BIT_AND		TOKEN(BIT_AND)
BIT_OR		TOKEN(BIT_OR)
BIT_XOR		TOKEN(BIT_XOR)
COUNT		TOKEN(COUNT)
MIN		TOKEN(MIN)
MAX		TOKEN(MAX)
SUM		TOKEN(SUM)
STD		TOKEN(STD)
STDDEV_SAMP		TOKEN(STDDEV_SAMP)
VARIANCE		TOKEN(VARIANCE)
VAR_SAMP		TOKEN(VAR_SAMP)
GROUP_CONCAT		TOKEN(GROUP_CONCAT)
SEPARATOR		TOKEN(SEPARATOR)
OVER		TOKEN(OVER)
IFNULL		TOKEN(IFNULL)
NULLIF		TOKEN(NULLIF)
END		TOKEN(END)
CASE		TOKEN(CASE)
THEN		TOKEN(THEN)
WHEN		TOKEN(WHEN)
ELSE		TOKEN(ELSE)
CAST		TOKEN(CAST)
CONVERT		TOKEN(CONVERT)
NCHAR		TOKEN(NCHAR)
">="		TOKEN(OP_GREATEREQ)
">"		TOKEN(OP_GREATERTHAN)
"<="		TOKEN(OP_LESSEQ)
"<"		TOKEN(OP_LESSTHAN)
"!="		TOKEN(OP_NOTEQUAL)
ANY		TOKEN(ANY)
SOME		TOKEN(SOME)

-?[0-9]+"."[0-9]* |
"."[0-9]* {
	yylval->double_value = atof(yytext);
	return SQL_FCONST;
}

-?[0-9]+ {
	yylval->long_value = atol(yytext);
	return SQL_ICONST;
}

[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] {

}

[-][-].* {

}

\'[^\']*\' {
	yylval->charp_value = strdup(yytext);
	return SQL_SCONST;
}

[A-Za-z$][A-Za-z0-9_]*[$]? {
	yylval->charp_value = strdup(yytext);
	return SQL_IDENT;
}

[ \t\n]+ {

}

. {
	return 0;
}

%%
